<template>
  <div ref="content" :style="{width: source.data.width || '100%', height: source.data.height||'100px'}"></div>
</template>

<script>
  let elementResizeDetectorMaker = require("element-resize-detector");
  export default {
    name: 'BarReportEngine', /* 这个name暂时不知道用啥用，根据官方文档说的是方便排错的 */
    data() {
      return {
        octopus: this.$parent.octopus,
        reportContent: null,  // 报表控件本身；
        color: {
          DarkGrey: "#515151", // 深灰色；
          Vigilance: "#E74D35", // 警戒色；
        },
      }
    },
    created: function () {
      this.init();
      this.octopus.tips.debug("BarReportEngine执行了created事件。");
    },
    // 只会执行一次
    mounted: function () {
      this.octopus.tips.debug("BarReportEngine执行了mounted事件。");
      // console.log(this.octopus.vue.$echarts);
      // let o = this;
      // // 基于准备好的dom，初始化echarts实例
      // this.reportContent = this.octopus.vue.$echarts.init(this.$refs.content);
      // // 注册拖拽事件。
      // // $(window).resize(function () {
      // //     if (o.octopus.tools.iframeRepair()) {
      // //         o.reportContent.resize();
      // //     }
      // // });
      // let erd = elementResizeDetectorMaker();
      // erd.listenTo(this.$refs.content, function (element) {
      //   o.$nextTick(function () {
      //     //使echarts尺寸重置
      //     if (o.octopus.tools.iframeRepair()) {
      //       o.reportContent.resize();
      //     }
      //   })
      // });
      // // 启用加载。
      // this.load();
      const that = this; //固定this指针到变量，防止后续this指向变更
      that.octopus.load.loadEcharts(that.load); //引入echarts
    },
    beforeUpdate: function () {
      // this.octopus.tips.debug("BarReportEngine执行了beforeUpdate事件。");
    },
    updated: function () {
      this.octopus.tips.debug("[BarReportEngine执行了updated事件。");
    },
    // 活动事件，写在这里的好处是不管是第一次创建还是后退回来，都会触发这个事件
    // 比较典型的就是列表组件，返回的时候往往是需要刷新的。
    activated: function () {
      this.octopus.tips.debug("BarReportEngine执行了activated事件。");
    },
    // 组件停用时，也就是切换出去的时候，需要注意的是，AppMenuEngine组件切换出去，不允许缓存，需要释放到初始状态，以便于下次进来。
    deactivated: function () {
      this.destroyData();
      this.octopus.tips.debug("BarReportEngine执行了deactivated事件。");
    },
    computed: {
      // 如果cellData数据发生了改变,则触发这个事件。
      changeCell: function () {
        return this.source.id;
      },
      changePage: function () {

      }
    },
    methods: {
      init: function () {
        this.initData();
      },
      // 初始化数据，主要是还原#param等预设参数，重新绑定。
      initData: function () {
        // 赋值。
        this.source.control = this;
      },
      // 执行加载
      load: function () {
        let o = this;
        this.octopus.request.api.post("/Octopus/Engine/List", this.source.data,
          // 处理回调事件，通过分析data.status.code的状态来实现。
          function (data) {
            if (data.status.code == 200) {

              // 初始化容器
              o.reportContent = echarts.init(o.$refs.content);

              // 数据初始化
              if (!o.source.report.xAxis.zoom) {
                o.source.report.xAxis.zoom = {};
              }
              // 渲染图表数据
              let optionData = {
                // backgroundColor: 'pink',
                // title: {
                //   text: o.source.report.title.name || "",
                //   subtext: o.source.report.title.note || "",
                //   x:o.source.report.title.local || "left",
                //   // top: 20, // 下沉20
                // },
                tooltip: {
                  trigger: 'axis',
                  axisPointer: {
                    type: 'cross',
                    crossStyle: {
                      color: '#00ff00'
                    },
                    // label: {
                    //   formatter: function (params) {
                    //     if (params.seriesData.length === 0) {
                    //       // 就是这里，可以获取到我想要的那个数据
                    //       mouseCurValue = params.value;
                    //     }
                    //   }
                    // }
                  },
                  // 展示面板格式化
                  formatter: function (params) {
                    let res = params[0].axisValue + "<br/>";
                    $(params).each(function (index, item) {
                      if (item.seriesId.indexOf("Vigilance") == -1) {
                        let color = $(o.source.report.cellData);
                        // 此处可对数据进行格式化显示，前端如果有配置就可以。
                        res +=
                          '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:' + color[index].color + ';"></span>' + item.seriesName + ":" + item.data + "<br/>";

                      }
                    });
                    return res;
                  },
                },
                toolbox: {
                  right: "20",
                  feature: {
                    dataView: {show: true, readOnly: false},
                    // magicType: {show: true, type: ['line', 'bar']},
                    // magicType: {show: true, type: ['line']},
                    // restore: {show: true},
                    saveAsImage: {show: true}
                  }
                },
                legend: {
                  // right: 10, // 各项偏移设置
                  // top: 20,
                  bottom: 40,
                  // data: ['用电量', '预算电量', '功率', '预算功率']
                  // selected: {'用电量': false, '预算用电量': false} // 后续可控制初始化显示或隐藏的列
                },
                xAxis: [
                  // {
                  //   type: 'category',
                  //   data: ['1月\n2019年', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
                  //   axisPointer: {
                  //     type: 'shadow'
                  //   },
                  //   axisLine: {
                  //     lineStyle: {
                  //       color: "#d14a61"
                  //     }
                  //   },
                  // }
                ],
                yAxis: [
                  // // min max 需要自动识别，并设置间隔值，一般按照6分来切割
                  // {
                  //   type: 'value',
                  //   name: '千瓦时',
                  //   min: -100,
                  //   max: 250,
                  //   interval: 50,
                  //   axisLabel: {
                  //     formatter: '{value} kWh'
                  //   }
                  // },
                  // {
                  //   type: 'value',
                  //   name: '千瓦',
                  //   min: 0,
                  //   max: 35,
                  //   interval: 5,
                  //   axisLine: {
                  //     lineStyle: {
                  //       color: "#d14a61"
                  //     }
                  //   },
                  //   axisLabel: {
                  //     formatter: '{value} kW'
                  //   }
                  // },
                  // {
                  //   type: 'value',
                  //   name: 'kW',
                  //   min: 0,
                  //   max: 25,
                  //   interval: 5,
                  //   offset: 80,
                  //   axisLabel: {
                  //     formatter: '{value} °T'
                  //   }
                  // }
                ],
                // 偏移使缩放条不遮掉报表X轴数据。
                grid: {
                  // top: "110px",
                  left: "60px",
                  right: "60px",
                  bottom: "100px",
                },
                dataZoom: [{
                  type: 'slider',//图表下方的伸缩条
                  show: o.source.report.xAxis.zoom.show || false, //是否显示，默认false
                  realtime: true, //拖动时，是否实时更新系列的视图
                  start: 0, //伸缩条开始位置（1-100），可以随时更改
                  end: o.source.report.xAxis.zoom.percentage || 100, //伸缩条结束位置（1-100），可以随时更改
                }],
                series: [
                  // {
                  //   name: '警戒线',
                  //   type: 'bar',
                  //   itemStyle: {
                  //     normal: {
                  //       color: "#FFEA00"
                  //     },
                  //   },
                  //   data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3]
                  // },
                  // {
                  //   name: '功率',
                  //   type: 'line',
                  //   yAxisIndex: 1,
                  //   itemStyle: {
                  //     normal: {
                  //       color: "#94B8EA"
                  //     },
                  //   },
                  //   data: [2.0, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3, 23.4, 23.0, 16.5, 12.0, 6.2]
                  // },
                ]
              };

              // 如果有设置头部属性，则渲染。
              if (o.source.report.title) {
                optionData.title = {
                  text: o.source.report.title.name || "",
                  subtext: o.source.report.title.note || "",
                  x: o.source.report.title.local || "left",
                  // top: 20, // 下沉20
                };
              }

              let xAxisData = [];
              // 转义数据
              let queryData = {};

              $(data.content.queryData).each(function (index, item) {
                // 根据X列的配置对象名称来判断数据中是否包含
                let xColumn = item[o.source.report.xAxis.name];
                if (xColumn) {
                  xAxisData.push(xColumn);
                }

                // 循环列名数据
                for (let p in item) {
                  if (!queryData[p]) {
                    queryData[p] = [];
                  }
                  // queryData[p].push(item[p] + (Math.ceil(Math.random() * 90)));
                  queryData[p].push(item[p]);
                }

              });

              // 装载X轴数据
              optionData.xAxis.push({
                type: 'category',
                data: xAxisData,
                axisPointer: {
                  type: 'shadow'
                },
                axisLine: {
                  lineStyle: {
                    color: o.source.report.xAxis.color || o.color.DarkGrey, // 默认深灰色
                  },
                },
                axisLabel: {
                  interval: 0, // 显示间隔
                  rotate: o.source.report.xAxis.slope || 0  // 文字倾斜
                }
              });


              // 装载报表Y轴数据，其中min、max需要自动根据最大值，最小值，然后根据split自动计算出min、max、interval。
              $(o.source.report.yAxis).each(function (index, item) {
                optionData.yAxis.push({
                  type: 'value',
                  name: item.name,
                  min: 0, // 默认 0 后续会自动填充
                  max: 0, // 默认 0 后续会自动填充
                  // max: function (value) {
                  //   return value.max;
                  //
                  // }.bind(this), // 通过bind实现this的绑定，关键点
                  ///////////////////////////// 最终还是要自己计算，在下面的cellData中计算完成，回过头重新设置min和max还有interval //////////////////////
                  // ES6 bind方法，参考：https://blog.csdn.net/m0_37885651/article/details/91417067
                  // interval: this.max / 5,// 数据量小于100的时候会有bug。。卧槽。。。
                  // interval: item.interval || 20, // 其中 interval 和 splitNumber 只能 二选一。
                  // splitNumber: 5,
                  // minInterval:0,
                  // boundaryGap : [ 0.2, 0.2 ], // 上下浮动
                  axisLine: {
                    lineStyle: {
                      color: item.color || o.color.DarkGrey,
                    },
                    // show:false,
                  },
                  axisLabel: {
                    formatter: "{value} " + item.unit
                  },
                  splitLine: {
                    // show:false, // 隐藏轴线
                  }
                },);

                // 装载警戒线数据，如果有Y轴警戒数据。
                if (item.vigilance) {
                  for (let vData in item.vigilance) {
                    // 创建警戒数据
                    let vigilanceData = [];
                    for (let i = 0; i < data.content.queryData.length; i++) {
                      vigilanceData.push(item.vigilance[vData]);
                    }
                    // 追加警戒数据包
                    optionData.series.push({
                      name: vData + "Vigilance",
                      type: "line", // 不设置的时候默认bar
                      yAxisIndex: index, // 警戒线使用的Y轴坐标，完美使用Index数据，哈哈哈。
                      showSymbol: false,  // 禁止警戒线出现原点
                      symbolSize: 0,      // 设置悬浮时警戒线的圈直径为0，变相隐藏，和showSymbol必须同时使用，否则鼠标移上去还是会有问题。
                      lineStyle: {       // 设置线样式
                        normal: {
                          color: o.color.Vigilance,
                          width: 1,// 线宽度
                          type: 'dashed', // 虚线
                        },
                      },
                      data: vigilanceData,
                    });
                  }
                }


              });

              // 定义列头数据
              let legendData = [];
              // y轴分割数据
              let yAxisSpiltData = [];

              // 装载报表列数据
              $(o.source.report.cellData).each(function (index, item) {
                let FilterColumn = $.grep(data.content.cellData, function (value) {
                  return value.name == item.name;//筛选出当前数据列数据
                });
                // 确保找到该列
                if (FilterColumn.length == 1) {
                  let column = FilterColumn[0];
                  // 拼装series数据
                  let seriesData = {
                    name: column.displayName,
                    type: item.type || "bar", // 不设置的时候默认bar
                    smooth: true, // 折线平滑曲线
                    yAxisIndex: item.yAxisIndex || 0,
                    barWidth: item.width || 20,// 默认 20 宽度
                    itemStyle: {
                      normal: {
                        // color: item.color || o.color.DarkGrey,
                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1,
                          [{
                            offset: 0,
                            color: o.octopus.tools.gradients(item.color || "#515151").start
                          },
                            {
                              offset: 1,
                              color: o.octopus.tools.gradients(item.color || "#515151").end
                            }]
                        )
                      },
                    },
                    // label: {
                    //   normal: {
                    //     formatter: ["aass"]
                    //   }
                    // },
                    // lineStyle: {},
                    // areaStyle: {},
                    data: queryData[column.name],
                  };

                  // 定义列头数据
                  legendData.push(column.displayName);
                  // 定义列数据
                  if (item.gradual) {
                    seriesData.areaStyle = {
                      color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                        offset: 0,
                        color: item.color || "rgb(255, 255, 255,0)"
                      }, {
                        offset: 1,
                        color: "rgb(255, 255, 255,0)" // 最后一位表示透明度，百度考虑的很全面。
                      }])
                    };
                  }

                  ////////////////////////////// 处理汇聚当前所有轴数据，获取min和max，适配单轴或双轴 //////////////////////////////
                  let yAxisData = {
                    name: column.name,
                    min: 0,
                    max: 0,
                    total_max: 0,
                    group: item.group || "RAM" + (Math.ceil(Math.random() * 100)),// 如果没有组，则智能分组。
                    index: seriesData.yAxisIndex
                  };
                  // 循环得到每个数据源最大和最小轴
                  $(queryData[column.name]).each(function (qn_index, qn_item) {
                    if (yAxisData.min > qn_item) {
                      yAxisData.min = qn_item;
                    }
                    if (yAxisData.max < qn_item) {
                      yAxisData.max = qn_item;
                      yAxisData.total_max = yAxisData.max;
                    }
                  });
                  // 导入y轴数据
                  yAxisSpiltData.push(yAxisData);

                  ////////////////////////////// 处理汇聚当前所有轴数据，获取min和max，适配单轴或双轴 //////////////////////////////

                  // 如果有分组信息，则写入。
                  if (item.group) {
                    seriesData.stack = item.group;
                  }


                  optionData.series.push(seriesData);
                } else {
                  o.octopus.tips.error("未找到列数据：" + item.name);
                }
              });

              ////////////////////////////// 更新y轴max数据，确保同组同索引的total_max肯定是一致的 //////////////////////////////
              $(yAxisSpiltData).each(function (index, item) {
                // 双重循环，获取所有分组的累计最大值
                $(yAxisSpiltData).each(function (each_index, each_item) {
                  // 如果组和索引一致，则累加，按照分组
                  if (item.group == each_item.group && item.index == each_item.index && item.name != each_item.name) {
                    item.total_max = item.total_max + each_item.max;
                  }
                });
              });
              // 因为已经分组分索引最大，所以循环一次，只分左边和右边（如果有）
              $(yAxisSpiltData).each(function (index, item) {
                // 左轴
                if (item.index == 0) {
                  let LeftAxis = optionData.yAxis[0];
                  if (LeftAxis.max < item.total_max) {
                    LeftAxis.max = o.setMax(item.total_max);
                    LeftAxis.interval = LeftAxis.max / 5;
                  }
                }
                // 右轴 且存在
                else if (item.index == 1) {
                  let RightAxis = optionData.yAxis[1];
                  if (RightAxis.max < item.total_max) {
                    RightAxis.max = o.setMax(item.total_max);
                    RightAxis.interval = RightAxis.max / 5;
                  }
                }
              });

              // 定义列头
              optionData.legend.data = legendData;
              // 执行渲染
              o.reportContent.setOption(optionData);

              // 执行事件
              o.reportContent.on('click', function (params) {
                if (o.clicked) {
                  o.clicked({
                    title: params.name,
                    name: params.seriesName,
                    value: params.value,
                    type: params.seriesType,
                  });
                }
              });

              o.reportContent.on('datazoom', function (params) {
                // console.log("zoom: "+optionData.yAxis[0].interval);
                // optionData.yAxis[0].interval = (Math.ceil(Math.random() * 200));
              });

              // 注册自适应大小接口。
              window.onresize = function () {
                resize();
              };
              function resize() {
                // 刷新以后重新定义宽度
                o.reportContent.resize();
              }

            } else {
              o.octopus.tips.error(data);
            }
          });

      },
      setMax: function (value) {
        let maxNumber = 0;
        // 最小化 10 值
        if (value < 10 || value == -Infinity) {
          maxNumber = 10;
        } else if (value < 100 || value == -Infinity) {
          maxNumber = (Math.ceil(parseFloat(value / 10)) * 10).toFixed(0);
        } else {
          maxNumber = (Math.ceil(parseFloat(value / 100)) * 110).toFixed(0);
        }
        return maxNumber;
      },
      // 组件停用时把data修正回原始数据，其他属性因为不会变，所以不用还原。
      destroyData: function () {

      },
      // 控件数据变更事件
      change: function (new_cell, old_cell) {

      },
    },
    watch: {},
    props: ["source", "changed", "clicked"]
  }

</script>

/*  scoped的意思是这里的样式只对当前页面有效不会影响其他页面，还有可以设置lang="scss"就是支持css预编译，也就是支持sass或者less  */
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  h1, h2 {
    font-weight: normal;
  }

</style>
